{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# !pip install bayesian-optimization"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import deepquantum as dq\n",
    "import deepquantum.photonic.circuit as circuit\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "\n",
    "from deepquantum.optimizer import *\n",
    "from deepquantum.photonic.decompose import *\n",
    "from scipy.stats import unitary_group\n",
    "\n",
    "np.set_printoptions(precision=8, floatmode='fixed', suppress=True) # to make the print info aligned\n",
    "\n",
    "N = 8\n",
    "u8x8 = unitary_group.rvs(N)\n",
    "decomp_rlt = UnitaryDecomposer(u8x8, \"cssr\").decomp()\n",
    "mzi_info = decomp_rlt[0]\n",
    "\n",
    "def zero_init(mzi_info):\n",
    "    for i in range(len(mzi_info['MZI_list'])):\n",
    "        mzi_info['MZI_list'][i][2] = 0.0\n",
    "        mzi_info['MZI_list'][i][3] = 0.0\n",
    "    mzi_info['phase_angle_ori'] = np.zeros(N)\n",
    "    mzi_info['phase_angle'] = np.zeros(N)\n",
    "\n",
    "def bar_securing(mzi_info):\n",
    "    adjustable_ids = []\n",
    "    for i in range(len(mzi_info['MZI_list'])):\n",
    "        if i not in adjustable_ids:\n",
    "            mzi_info['MZI_list'][i][-1] = np.pi\n",
    "            mzi_info['MZI_list'][i][-2] = np.pi\n",
    "    \n",
    "def xx_planting(mzi_info):\n",
    "    for i in [20, 24]:\n",
    "        mzi_info['MZI_list'][i][-1] = np.pi/2\n",
    "\n",
    "def yy_planting(mzi_info):\n",
    "    for i in [20, 24]:\n",
    "        mzi_info['MZI_list'][i][-1] = np.pi/2\n",
    "        mzi_info['MZI_list'][i][-2] = np.pi\n",
    "\n",
    "def zz_planting(mzi_info):\n",
    "    for i in [20, 24]:\n",
    "        mzi_info['MZI_list'][i][-1] = np.pi\n",
    "        mzi_info['MZI_list'][i][-2] = np.pi\n",
    "\n",
    "def zx_planting(mzi_info):\n",
    "    mzi_info['MZI_list'][20][-1] = np.pi\n",
    "    mzi_info['MZI_list'][20][-2] = np.pi\n",
    "    mzi_info['MZI_list'][24][-1] = np.pi/2\n",
    "\n",
    "\n",
    "def trial_planting(mzi_info,angle_list):\n",
    "    change_list = [[1,-1],\n",
    "                   [4,-1],\n",
    "                   [5,-1]]\n",
    "    for i in range(len(angle_list)):\n",
    "        a,b = change_list[i]\n",
    "        mzi_info['MZI_list'][a][b] = angle_list[i]\n",
    "        \n",
    "zero_init(mzi_info)\n",
    "bar_securing(mzi_info)\n",
    "zz_planting(mzi_info)\n",
    "\n",
    "\n",
    "def post_selection(rlt_strkey):\n",
    "    # print(rlt_strkey)\n",
    "    label_list = ['|00101000>', '|00100100>', '|00011000>', '|00010100>']\n",
    "    value = np.zeros(4)\n",
    "    for i in range(4):\n",
    "        try:\n",
    "            value[i] = rlt_strkey[label_list[i]]\n",
    "        except:\n",
    "            pass\n",
    "    return value\n",
    "\n",
    "\n",
    "def estimate_energy(post_selection_rlt,type='ZZ'):\n",
    "    norm = post_selection_rlt/(post_selection_rlt.sum()+1e-16)\n",
    "    if type=='ZZ': # ZZ basis\n",
    "        return norm[0]+norm[3]-norm[1]-norm[2]\n",
    "    if type=='ZI': # ZI basis\n",
    "        return norm[0]+norm[1]-norm[2]-norm[3]\n",
    "    if type=='IZ': # IZ basis\n",
    "        return -norm[0]-norm[1]+norm[2]+norm[3]\n",
    "\n",
    "def compute_process(mzi_info):\n",
    "    cir = circuit.QumodeCircuit(nmode=8,init_state=[0,0, 0, 1, 0, 1, 0,0], name=\"test\", cutoff = 3, basis = True) # basis=True, using state list \n",
    "    for info in mzi_info['MZI_list']:\n",
    "        cir.ps(inputs=info[2],wires=[info[0]])\n",
    "        cir.bs_theta(inputs=np.pi/4,wires=[info[0],info[1]])\n",
    "        cir.ps(inputs=info[3],wires=[info[0]])\n",
    "        cir.bs_theta(inputs=np.pi/4,wires=[info[0],info[1]])\n",
    "    rlt = cir()\n",
    "    rlt_strkey = dict()\n",
    "    for key in rlt.keys():\n",
    "        rlt_strkey[str(key)] = np.abs(rlt[key].detach().numpy().squeeze())**2\n",
    "\n",
    "    # rltm = cir.measure(shots=10000)[0]\n",
    "    # rltm_strkey = dict()\n",
    "    # for key in rltm.keys():\n",
    "    #     rltm_strkey[str(key)] = rltm[key]\n",
    "    # return post_selection(rltm_strkey)\n",
    "\n",
    "    return post_selection(rlt_strkey)\n",
    "\n",
    "def estimate_eigval(angle_list):\n",
    "    # to minimize\n",
    "    zero_init(mzi_info)\n",
    "    bar_securing(mzi_info)\n",
    "    trial_planting(mzi_info,angle_list)\n",
    "\n",
    "    zz_planting(mzi_info)\n",
    "    post_selection_rlt = compute_process(mzi_info)\n",
    "    e_zz = estimate_energy(post_selection_rlt)\n",
    "\n",
    "    xx_planting(mzi_info)\n",
    "    post_selection_rlt = compute_process(mzi_info)\n",
    "    e_xx = estimate_energy(post_selection_rlt)\n",
    "\n",
    "    yy_planting(mzi_info)\n",
    "    post_selection_rlt = compute_process(mzi_info)\n",
    "    e_yy = estimate_energy(post_selection_rlt)\n",
    "    \n",
    "    return (1 + e_zz - e_xx - e_yy) / 2  \n",
    "\n",
    "    # zz_planting(mzi_info)\n",
    "    # post_selection_rlt = compute_process(mzi_info)\n",
    "    # e_zi = estimate_energy(post_selection_rlt,type='ZI')\n",
    "\n",
    "    # xx_planting(mzi_info)\n",
    "    # post_selection_rlt = compute_process(mzi_info)\n",
    "    # e_ix = estimate_energy(post_selection_rlt,type='IZ')\n",
    "\n",
    "    # zx_planting(mzi_info)\n",
    "    # post_selection_rlt = compute_process(mzi_info)\n",
    "    # e_zx = estimate_energy(post_selection_rlt,type='ZZ')\n",
    "    \n",
    "    # return (1 + e_zi + e_ix - e_zx) / 2  \n",
    "\n",
    "\n",
    "def target_function(angle_list):\n",
    "    # to maximize\n",
    "    return -estimate_eigval(angle_list)\n",
    "\n",
    "def void_target():\n",
    "    return -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "==================================================\n",
      "运行BO\n",
      "轮次 \t 参数值 \t                                 目标值\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 \t [3.44829694 4.49366732 3.78727399] \t  0.3947972653  *\n",
      "2 \t [0.04130112 0.38026479 0.23805479] \t  0.1257407466  *\n",
      "3 \t [1.44694751 6.01625953 2.40802370] \t  0.9167352244   \n",
      "4 \t [3.39985388 3.47527230 4.60283868] \t  0.9266207489   \n",
      "5 \t [1.22734700 1.73043008 0.54248881] \t -0.6500056711  *\n",
      "6 \t [2.09069562 1.41932526 0.00000000] \t -0.7981043946  *\n",
      "7 \t [2.88304816 2.97512045 0.00000000] \t -0.9091092168  *\n",
      "8 \t [5.18323663 1.69216123 0.00000000] \t  0.8385735512   \n",
      "9 \t [1.38723141 3.44086540 0.00000000] \t  0.2468208299   \n",
      "10 \t [2.63688277 2.14576832 0.98241740] \t  0.2032860750   \n",
      "11 \t [3.36385140 3.65330729 0.00000000] \t -0.7218107201   \n",
      "12 \t [1.78490675 0.45700257 0.35228934] \t -0.3414096053   \n",
      "13 \t [4.20399059 5.04937878 0.00000000] \t -0.7101006858   \n",
      "14 \t [5.48218048 5.61032775 0.00000000] \t -0.9820068680  *\n",
      "15 \t [5.03704579 6.28318531 0.99640996] \t  0.5997025340   \n",
      "16 \t [5.36604905 4.69659434 0.00000000] \t -0.7862136042   \n",
      "17 \t [6.23089379 5.28085801 0.56497262] \t  0.1455149062   \n",
      "18 \t [4.50518663 4.12427183 0.39553909] \t -0.7668301341   \n",
      "19 \t [3.55915589 4.25868064 1.12214239] \t  0.4017566378   \n",
      "20 \t [3.90560700 3.06980542 0.08846628] \t  0.1861078373   \n",
      "21 \t [4.92095092 5.41328475 0.03388588] \t -0.8622318719   \n",
      "22 \t [2.57461439 3.95351346 0.04907244] \t  0.9288746456   \n",
      "23 \t [1.18368779 0.57158867 2.12243712] \t  0.3813670780   \n",
      "24 \t [2.66993198 6.13501133 3.80194037] \t  0.1627471909   \n",
      "25 \t [4.79680291 4.78017827 0.38123244] \t -0.8892676438   \n",
      "26 \t [2.27391462 2.28567814 0.00000000] \t -0.9998799078  *\n",
      "27 \t [2.91718018 2.04860286 0.00000000] \t -0.3581869526   \n",
      "28 \t [1.58309208 2.10644568 0.00000000] \t -0.8653025437   \n",
      "29 \t [0.25267243 2.15017943 0.00000000] \t -0.1367170030   \n",
      "30 \t [5.39317846 4.00898615 1.20088594] \t -0.0502625550   \n",
      "31 \t [6.28318531 0.00000000 6.28318531] \t  0.8391323174   \n",
      "32 \t [0.00000000 0.00000000 6.28318531] \t  1.0891093388   \n",
      "33 \t [6.28318531 6.28318531 6.28318531] \t  0.4492546671   \n",
      "34 \t [0.00000000 6.28318531 6.28318531] \t  0.9658551951   \n",
      "35 \t [6.28318531 0.00000000 2.74660080] \t  1.0000000000   \n",
      "36 \t [0.00000000 2.75619317 1.94258802] \t  0.0252951459   \n",
      "37 \t [0.00000000 3.09258296 4.52779375] \t  0.0003553637   \n",
      "38 \t [4.59980151 4.46123851 0.00000000] \t -0.9901402085   \n",
      "39 \t [6.28318531 3.28837500 6.28318531] \t -0.0000000299   \n",
      "40 \t [3.14171062 0.00000000 4.86355975] \t  0.0000000654   \n",
      "41 \t [3.10336651 0.00000000 0.00000000] \t -0.0000000298   \n",
      "42 \t [3.35742766 6.28318531 6.28318531] \t  0.0000000300   \n",
      "43 \t [6.28318531 3.89172674 3.79405711] \t  0.1221012409   \n",
      "44 \t [0.00000000 6.28318531 0.00000000] \t  0.8564943196   \n",
      "45 \t [1.02080870 2.93276258 6.23139274] \t -0.1164699804   \n",
      "46 \t [2.55629066 1.41412155 6.24741315] \t -0.4826307836   \n",
      "47 \t [3.93663540 1.54852598 6.27937672] \t  0.7027601965   \n",
      "48 \t [1.74555359 1.52588869 5.54430302] \t -0.6245312484   \n",
      "49 \t [2.11287547 0.42955560 6.08188626] \t -0.2405409105   \n",
      "50 \t [1.83910971 1.27191034 4.40419437] \t -0.0903194867   \n",
      "51 \t [1.54824966 1.73173301 6.28318531] \t -0.9832745285   \n",
      "52 \t [2.06786101 2.15300677 5.96888519] \t -0.8834751324   \n",
      "53 \t [6.28318531 6.28318531 3.69766066] \t  1.0000001240   \n",
      "54 \t [0.75616123 1.83427987 5.56127144] \t -0.2845439047   \n",
      "55 \t [3.39815166 0.00000000 2.82335022] \t  0.0176630217   \n",
      "56 \t [1.23652005 1.22409124 0.00000000] \t -0.9999130745  *\n",
      "57 \t [2.31103513 3.46599325 6.27869964] \t  0.6523956131   \n",
      "58 \t [0.00000000 0.00000000 3.65701452] \t  0.9999999075   \n",
      "59 \t [6.19314157 6.28318531 0.00000000] \t  0.0000043455   \n",
      "60 \t [0.00000000 4.35416425 3.29466695] \t  0.3234098415   \n",
      "61 \t [6.28318531 2.58867485 2.51534341] \t  0.0679129401   \n",
      "62 \t [6.04954114 2.18632672 4.55123791] \t  0.2037422128   \n",
      "63 \t [6.26987281 0.01260730 0.03521787] \t  0.9996259423   \n",
      "64 \t [1.66592707 2.50590213 4.89517155] \t  0.1420429210   \n",
      "65 \t [4.90062237 4.71536705 6.28318531] \t -0.9828796450   \n",
      "66 \t [5.35437043 4.69524011 5.48609700] \t -0.3425629156   \n",
      "67 \t [4.56618607 5.44593832 6.28318531] \t -0.6695709110   \n",
      "68 \t [4.16220067 4.52478650 6.28318531] \t -0.9279576151   \n",
      "69 \t [4.81708276 3.79133916 6.18280524] \t -0.5484384880   \n",
      "70 \t [4.20043248 4.91664543 5.62532154] \t -0.6170160034   \n",
      "71 \t [4.16332398 6.28318531 4.83613311] \t  0.9003783659   \n",
      "72 \t [3.59463380 5.07913979 6.28318531] \t -0.3089763243   \n",
      "73 \t [6.28318531 3.50706186 0.00000000] \t -0.0000000606   \n",
      "74 \t [3.97900747 4.23669099 0.00000000] \t -0.9523873945   \n",
      "75 \t [4.57668528 4.49155252 6.02339928] \t -0.9410571488   \n",
      "76 \t [0.00000000 2.32449682 6.28318531] \t  0.0000000000   \n",
      "77 \t [1.98016927 1.88079457 6.28318531] \t -0.9943845601   \n",
      "78 \t [4.45493465 4.85539504 6.28318531] \t -0.9236521465   \n",
      "79 \t [6.28318531 4.62891011 6.28318531] \t  0.0000001620   \n",
      "80 \t [1.57074211 2.18454465 6.28318531] \t -0.8174695504   \n",
      "81 \t [2.31157387 2.72023167 0.00000000] \t -0.7856527654   \n",
      "82 \t [3.98045227 1.35779048 3.54776349] \t  1.1812208066   \n",
      "83 \t [0.01133897 3.78416721 0.06053362] \t  0.0038646276   \n",
      "84 \t [1.55989753 1.54698407 0.00000000] \t -0.9999166024  *\n",
      "85 \t [0.00000000 6.28318531 3.96253797] \t  1.0000000000   \n",
      "86 \t [2.24910748 0.06345328 3.73379383] \t  0.1798015489   \n",
      "87 \t [1.77421150 1.84111101 6.01012152] \t -0.9352933508   \n",
      "88 \t [5.35286563 5.22975750 0.00000000] \t -0.9892563249   \n",
      "89 \t [1.67769182 1.13518384 6.27147971] \t -0.8625441442   \n",
      "90 \t [1.99338739 1.93088744 0.00000000] \t -0.9977176964   \n",
      "91 \t [1.14567572 0.00000000 0.00000000] \t -0.0000001100   \n",
      "92 \t [0.00000000 2.18141417 3.39500146] \t  0.2106239640   \n",
      "93 \t [4.30549719 4.53170060 0.22250959] \t -0.9378015436   \n",
      "94 \t [2.86341150 0.00000000 1.51398245] \t  0.7413737272   \n",
      "95 \t [1.55581327 1.05583984 0.00000000] \t -0.8766852832   \n",
      "96 \t [4.49698943 4.29902380 6.27610579] \t -0.9785875277   \n",
      "97 \t [1.12270522 1.33950952 6.28318531] \t -0.9740085589   \n",
      "98 \t [1.04713748 1.57377755 0.00000000] \t -0.8647023755   \n",
      "99 \t [0.93844275 1.11212206 0.58306536] \t -0.6101809041   \n",
      "100 \t [4.81342790 4.85309068 0.04966931] \t -0.9973667205   \n",
      "BO结果： -0.9999166024311785\n"
     ]
    }
   ],
   "source": [
    "# 测试BO算法\n",
    "print(\"=\"*50)\n",
    "print(\"运行BO\")\n",
    "param_init = {'t1':0, 't2':0, 't3':0}\n",
    "bo_optimizer = OptimizerBayesian(target_func=void_target,param_init=param_init,random_state=0)\n",
    "\n",
    "print(\"轮次\",\"\\t\",\"参数值\",\"\\t\",\" \"*31,\"目标值\")\n",
    "for _ in range(100):\n",
    "    # 待片上计算的参数\n",
    "    p1 = bo_optimizer.param_suggest()\n",
    "    # 模拟芯片计算过程，之后需要替换成接口\n",
    "    f1 = -estimate_eigval(p1.tolist()) #  BO 内置用法是最大化目标；但是接下来打印时再添一个符号即可\n",
    "    # 测试结果传回，更新param_dict\n",
    "    bo_optimizer.param_register([p1],[f1])\n",
    "    f1_to_print = -f1\n",
    "    if bo_optimizer.best_target == f1:\n",
    "        mark = \"*\"\n",
    "    else:\n",
    "        mark = \" \"\n",
    "    if f1_to_print<0:\n",
    "        print(bo_optimizer.iter,\"\\t\",p1,\"\\t\",f\"{f1_to_print:8.10f} \",mark)\n",
    "    else:\n",
    "        print(bo_optimizer.iter,\"\\t\",p1,\"\\t \",f\"{f1_to_print:8.10f} \",mark)\n",
    "\n",
    "print(\"BO结果：\",estimate_eigval(list(bo_optimizer.best_param_dict.values())))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "==================================================\n",
      "运行SPSA\n",
      "轮次 \t 参数值 \t                                 目标值\n",
      "1 \t [ 0.12604016  0.56353842 -0.19234807] \t -0.2716579327 \n",
      "1 \t [ 0.10604016  0.58353842 -0.17234807] \t -0.2368486010 \n",
      "2 \t [ 0.13251132  0.55706726 -0.19881923] \t -0.2815470800 \n",
      "2 \t [ 0.11386359  0.57571499 -0.18017150] \t -0.2511828906 \n",
      "3 \t [ 0.12090446  0.55077463 -0.20511187] \t -0.2414854959 \n",
      "3 \t [ 0.13880395  0.56867412 -0.18721237] \t -0.3120761031 \n",
      "4 \t [ 0.13725956  0.56712973 -0.17136987] \t -0.3290447820 \n",
      "4 \t [ 0.15464645  0.58451662 -0.18875676] \t -0.3470358360 \n",
      "5 \t [ 0.15866422  0.57153497 -0.17577511] \t -0.3787760432 \n",
      "5 \t [ 0.14166481  0.58853439 -0.19277453] \t -0.3072688953 \n",
      "6 \t [ 0.17557938  0.57130907 -0.15885996] \t -0.4438339907 \n",
      "6 \t [ 0.15889013  0.55461982 -0.17554921] \t -0.3858477528 \n",
      "7 \t [ 0.18950900  0.56880727 -0.14493033] \t -0.4967707240 \n",
      "7 \t [ 0.17307758  0.58523869 -0.16136175] \t -0.4279756788 \n",
      "8 \t [ 0.19007913  0.55202584 -0.12814891] \t -0.5279164826 \n",
      "8 \t [ 0.20629043  0.56823714 -0.14436021] \t -0.5378905594 \n",
      "9 \t [ 0.20866961  0.55459673 -0.14673938] \t -0.5485571001 \n",
      "9 \t [ 0.19265001  0.57061632 -0.13071979] \t -0.5196254067 \n",
      "10 \t [ 0.19997906  0.54743725 -0.13804884] \t -0.5432633298 \n",
      "10 \t [ 0.21582909  0.56328727 -0.15389887] \t -0.5507175221 \n",
      "11 \t [ 0.20193601  0.56509237 -0.15570397] \t -0.5153006405 \n",
      "11 \t [ 0.21763419  0.54939419 -0.14000579] \t -0.5809250319 \n",
      "12 \t [ 0.23423791  0.53279048 -0.13896290] \t -0.6295652052 \n",
      "12 \t [ 0.21867708  0.54835131 -0.12340207] \t -0.6039688991 \n",
      "13 \t [ 0.24071696  0.52631143 -0.14544195] \t -0.6384658660 \n",
      "13 \t [ 0.22528142  0.54174696 -0.13000641] \t -0.6155360868 \n",
      "14 \t [ 0.24655047  0.53579835 -0.15127546] \t -0.6365134821 \n",
      "14 \t [ 0.23123003  0.52047792 -0.13595503] \t -0.6351679914 \n",
      "15 \t [ 0.24684457  0.52087841 -0.15156956] \t -0.6454745730 \n",
      "15 \t [ 0.23163052  0.53609245 -0.13635552] \t -0.6252273017 \n",
      "16 \t [ 0.23692795  0.51567983 -0.15676814] \t -0.6200077134 \n",
      "16 \t [ 0.25204315  0.53079503 -0.14165294] \t -0.6639959479 \n",
      "17 \t [ 0.26344111  0.52717006 -0.13025498] \t -0.7035592243 \n",
      "17 \t [ 0.24841818  0.54219299 -0.14527791] \t -0.6446802961 \n",
      "18 \t [ 0.26383080  0.51184391 -0.12986529] \t -0.7150633645 \n",
      "18 \t [ 0.27876725  0.52678037 -0.11492883] \t -0.7503417350 \n",
      "19 \t [ 0.27310803  0.53597626 -0.12058806] \t -0.7272121967 \n",
      "19 \t [ 0.28796314  0.52112115 -0.10573294] \t -0.7802949059 \n",
      "20 \t [ 0.30186050  0.52200214 -0.10661394] \t -0.8007111848 \n",
      "20 \t [ 0.28708215  0.50722379 -0.09183559] \t -0.8037588117 \n",
      "21 \t [ 0.28631643  0.52116378 -0.10577558] \t -0.7774971898 \n",
      "21 \t [ 0.30102213  0.50645807 -0.09106987] \t -0.8266525834 \n",
      "22 \t [ 0.31395233  0.49352788 -0.07813968] \t -0.8661287258 \n",
      "22 \t [ 0.29931555  0.50816465 -0.09277645] \t -0.8211646827 \n",
      "23 \t [ 0.32580225  0.49624915 -0.06628975] \t -0.8885385680 \n",
      "23 \t [ 0.31123105  0.48167795 -0.08086095] \t -0.8685322502 \n",
      "24 \t [ 0.33106754  0.48700574 -0.07553316] \t -0.8935874314 \n",
      "24 \t [ 0.31655884  0.50151444 -0.06102446] \t -0.8768948905 \n",
      "25 \t [ 0.33546403  0.49705826 -0.06548064] \t -0.8996795756 \n",
      "25 \t [ 0.32101502  0.48260925 -0.07992965] \t -0.8809526916 \n",
      "26 \t [ 0.32601653  0.48761075 -0.06053626] \t -0.8989986561 \n",
      "26 \t [ 0.34040841  0.50200264 -0.07492815] \t -0.8947072603 \n",
      "27 \t [ 0.32490285  0.50083421 -0.05942258] \t -0.8889215578 \n",
      "27 \t [ 0.33923998  0.48649707 -0.07375971] \t -0.9042131742 \n",
      "28 \t [ 0.32899978  0.49673727 -0.07780408] \t -0.8828580749 \n",
      "28 \t [ 0.34328435  0.48245271 -0.06351951] \t -0.9186804836 \n",
      "29 \t [ 0.33857082  0.47293221 -0.06823304] \t -0.9163239454 \n",
      "29 \t [ 0.35280485  0.48716623 -0.05399901] \t -0.9309975344 \n",
      "30 \t [ 0.34250885  0.47687024 -0.05010964] \t -0.9301336007 \n",
      "30 \t [ 0.35669422  0.49105561 -0.06429501] \t -0.9255523067 \n",
      "31 \t [ 0.34767172  0.48203311 -0.05527251] \t -0.9286423686 \n",
      "31 \t [ 0.34908557  0.48344696 -0.05668636] \t -0.9281973429 \n",
      "32 \t [ 0.34789456  0.48084663 -0.05408603] \t -0.9303066970 \n",
      "32 \t [ 0.34648524  0.48225595 -0.05549535] \t -0.9272595139 \n",
      "33 \t [ 0.35603688  0.47270431 -0.04734866] \t -0.9459847948 \n",
      "33 \t [ 0.35463194  0.47410925 -0.04594371] \t -0.9447990521 \n",
      "34 \t [ 0.35920566  0.46953552 -0.04911672] \t -0.9492173243 \n",
      "34 \t [ 0.35780495  0.47093624 -0.05051744] \t -0.9465810398 \n",
      "35 \t [ 0.36625661  0.46248457 -0.04206577] \t -0.9615357493 \n",
      "35 \t [ 0.36485999  0.46388120 -0.04346239] \t -0.9592236919 \n",
      "36 \t [ 0.37244244  0.45769141 -0.03727260] \t -0.9697922018 \n",
      "36 \t [ 0.37104978  0.45629875 -0.03587995] \t -0.9701990318 \n",
      "37 \t [ 0.36996258  0.45660036 -0.03618156] \t -0.9692995211 \n",
      "37 \t [ 0.37135139  0.45521156 -0.03479275] \t -0.9713056781 \n",
      "38 \t [ 0.37672138  0.45122663 -0.02942276] \t -0.9778901303 \n",
      "38 \t [ 0.37533631  0.44984156 -0.03080783] \t -0.9772560236 \n",
      "39 \t [ 0.37841778  0.45292303 -0.02910780] \t -0.9781669985 \n",
      "39 \t [ 0.37703634  0.45154159 -0.02772636] \t -0.9784920408 \n",
      "40 \t [ 0.37754543  0.45067276 -0.02685754] \t -0.9793693997 \n",
      "40 \t [ 0.37616751  0.45205068 -0.02823545] \t -0.9776801631 \n",
      "41 \t [ 0.38069384  0.44614987 -0.02370913] \t -0.9834826036 \n",
      "41 \t [ 0.38206832  0.44752435 -0.02233464] \t -0.9839582116 \n",
      "42 \t [ 0.38196942  0.44742544 -0.02106241] \t -0.9842765589 \n",
      "42 \t [ 0.38334056  0.44879658 -0.02243355] \t -0.9840244231 \n",
      "43 \t [ 0.38129574  0.44675177 -0.02175663] \t -0.9840525576 \n",
      "43 \t [ 0.38266363  0.44811965 -0.02038874] \t -0.9844900993 \n",
      "44 \t [ 0.38246908  0.44928982 -0.02058329] \t -0.9839329014 \n",
      "44 \t [ 0.38383379  0.44792510 -0.01921858] \t -0.9853297975 \n",
      "45 \t [ 0.38621099  0.44554790 -0.01547976] \t -0.9878658000 \n",
      "45 \t [ 0.38757261  0.44418628 -0.01684138] \t -0.9885633409 \n",
      "46 \t [ 0.38807990  0.44367900 -0.01734866] \t -0.9888063414 \n",
      "46 \t [ 0.38943850  0.44232040 -0.01870726] \t -0.9894122073 \n",
      "47 \t [ 0.39105862  0.44205593 -0.02032738] \t -0.9896662456 \n",
      "47 \t [ 0.38970297  0.44070028 -0.01897173] \t -0.9899165815 \n",
      "48 \t [ 0.38903456  0.44138465 -0.01830333] \t -0.9896384228 \n",
      "48 \t [ 0.39038734  0.44003188 -0.01965610] \t -0.9901756601 \n",
      "49 \t [ 0.39047305  0.43994616 -0.02109178] \t -0.9898823054 \n",
      "49 \t [ 0.39182301  0.43859620 -0.01974182] \t -0.9909993551 \n",
      "50 \t [ 0.39346146  0.43561054 -0.01810337] \t -0.9925973647 \n",
      "50 \t [ 0.39480867  0.43695775 -0.01675616] \t -0.9929191388 \n",
      "51 \t [ 0.39566744  0.43781652 -0.01589739] \t -0.9931111275 \n",
      "51 \t [ 0.39432293  0.43647201 -0.01724190] \t -0.9928060127 \n",
      "52 \t [ 0.39513950  0.43863046 -0.01642533] \t -0.9926673473 \n",
      "52 \t [ 0.39648138  0.43728858 -0.01508345] \t -0.9936009188 \n",
      "53 \t [ 0.39763418  0.43479648 -0.01259135] \t -0.9948519407 \n",
      "53 \t [ 0.39897348  0.43613578 -0.01393065] \t -0.9946754805 \n",
      "54 \t [ 0.39716437  0.43566344 -0.01212154] \t -0.9946172720 \n",
      "54 \t [ 0.39850115  0.43432666 -0.01345831] \t -0.9950207623 \n",
      "55 \t [ 0.39824224  0.43458558 -0.01453370] \t -0.9947301125 \n",
      "55 \t [ 0.39957654  0.43325128 -0.01319940] \t -0.9955163500 \n",
      "56 \t [ 0.40034028  0.43248753 -0.01110378] \t -0.9961219304 \n",
      "56 \t [ 0.40167215  0.43115566 -0.01243566] \t -0.9964378272 \n",
      "57 \t [ 0.40118349  0.43164432 -0.01327649] \t -0.9961322043 \n",
      "57 \t [ 0.40251298  0.43031483 -0.01194699] \t -0.9968014970 \n",
      "58 \t [ 0.40429481  0.42853300 -0.01016516] \t -0.9975987327 \n",
      "58 \t [ 0.40296765  0.42986016 -0.01149233] \t -0.9970158168 \n",
      "59 \t [ 0.40452077  0.42830704 -0.00993920] \t -0.9976916839 \n",
      "59 \t [ 0.40584565  0.42698216 -0.00861433] \t -0.9981994333 \n",
      "60 \t [ 0.40719557  0.42695487 -0.00726441] \t -0.9985018659 \n",
      "60 \t [ 0.40587294  0.42563225 -0.00858703] \t -0.9983692187 \n",
      "61 \t [ 0.40622678  0.42730650 -0.00823319] \t -0.9982473145 \n",
      "61 \t [ 0.40754720  0.42598608 -0.00691278] \t -0.9986827628 \n",
      "62 \t [ 0.40870331  0.42482997 -0.00575666] \t -0.9990123679 \n",
      "62 \t [ 0.40738506  0.42614822 -0.00707491] \t -0.9986326631 \n",
      "63 \t [ 0.40971064  0.42513876 -0.00474933] \t -0.9991442422 \n",
      "63 \t [ 0.40839452  0.42382264 -0.00606546] \t -0.9990553549 \n",
      "64 \t [ 0.40994550  0.42405959 -0.00451448] \t -0.9992736046 \n",
      "64 \t [ 0.40863146  0.42537362 -0.00582851] \t -0.9989469383 \n",
      "65 \t [ 0.41081082  0.42319427 -0.00364916] \t -0.9994547054 \n",
      "65 \t [ 0.40949884  0.42450624 -0.00496113] \t -0.9991695435 \n",
      "66 \t [ 0.41156554  0.42374949 -0.00420438] \t -0.9994457567 \n",
      "66 \t [ 0.41025559  0.42243954 -0.00289443] \t -0.9994970761 \n",
      "67 \t [ 0.41142864  0.42361259 -0.00406748] \t -0.9994520151 \n",
      "67 \t [ 0.41012068  0.42230462 -0.00275951] \t -0.9995012570 \n",
      "68 \t [ 0.41129735  0.42217529 -0.00263018] \t -0.9995984034 \n",
      "68 \t [ 0.40999134  0.42348130 -0.00393619] \t -0.9993539518 \n",
      "69 \t [ 0.41194280  0.42152984 -0.00328882] \t -0.9996561485 \n",
      "69 \t [ 0.41063872  0.42283393 -0.00198473] \t -0.9995231482 \n",
      "70 \t [ 0.41229328  0.42248155 -0.00233711] \t -0.9996522838 \n",
      "70 \t [ 0.41099109  0.42117936 -0.00363930] \t -0.9996044667 \n",
      "71 \t [ 0.41111827  0.42130654 -0.00221179] \t -0.9996537906 \n",
      "71 \t [ 0.41241860  0.42260687 -0.00351212] \t -0.9996123404 \n",
      "72 \t [ 0.41230833  0.42249660 -0.00210335] \t -0.9996583842 \n",
      "72 \t [ 0.41100984  0.42119811 -0.00340185] \t -0.9996143200 \n",
      "73 \t [ 0.41242358  0.42131516 -0.00198810] \t -0.9997357491 \n",
      "73 \t [ 0.41112690  0.42261185 -0.00328479] \t -0.9995345699 \n",
      "74 \t [ 0.41165767  0.42208108 -0.00145911] \t -0.9996562375 \n",
      "74 \t [ 0.41295257  0.42078617 -0.00275402] \t -0.9997684411 \n",
      "75 \t [ 0.41324698  0.42049176 -0.00304843] \t -0.9997855094 \n",
      "75 \t [ 0.41195383  0.42178491 -0.00175528] \t -0.9996872302 \n",
      "76 \t [ 0.41221312  0.42152563 -0.00201456] \t -0.9997117669 \n",
      "76 \t [ 0.41350454  0.42023420 -0.00330599] \t -0.9997978748 \n",
      "77 \t [ 0.41244020  0.42000883 -0.00353136] \t -0.9997515382 \n",
      "77 \t [ 0.41372992  0.42129854 -0.00224165] \t -0.9997964755 \n",
      "78 \t [ 0.41255900  0.42141567 -0.00212452] \t -0.9997345017 \n",
      "78 \t [ 0.41384704  0.42012763 -0.00341256] \t -0.9998116113 \n",
      "79 \t [ 0.41404845  0.41992622 -0.00361397] \t -0.9998182649 \n",
      "79 \t [ 0.41276207  0.42121260 -0.00232759] \t -0.9997506310 \n",
      "80 \t [ 0.41422487  0.41974980 -0.00250564] \t -0.9998702197 \n",
      "80 \t [ 0.41294012  0.42103455 -0.00379039] \t -0.9997161958 \n",
      "81 \t [ 0.41462732  0.41934735 -0.00210319] \t -0.9999062115 \n",
      "81 \t [ 0.41334418  0.42063049 -0.00338633] \t -0.9997710579 \n",
      "82 \t [ 0.41369851  0.41899461 -0.00303200] \t -0.9998603012 \n",
      "82 \t [ 0.41498006  0.42027616 -0.00175045] \t -0.9998968821 \n",
      "83 \t [ 0.41379490  0.42037098 -0.00165563] \t -0.9998522172 \n",
      "83 \t [ 0.41507488  0.41909100 -0.00293561] \t -0.9999004627 \n",
      "84 \t [ 0.41520008  0.41896580 -0.00306081] \t -0.9999020120 \n",
      "84 \t [ 0.41392164  0.42024423 -0.00178238] \t -0.9998596209 \n",
      "85 \t [ 0.41403299  0.42013288 -0.00317063] \t -0.9998278283 \n",
      "85 \t [ 0.41530990  0.41885598 -0.00189373] \t -0.9999407219 \n",
      "86 \t [ 0.41432798  0.41856249 -0.00287564] \t -0.9998967054 \n",
      "86 \t [ 0.41560338  0.41983789 -0.00160024] \t -0.9999305983 \n",
      "87 \t [ 0.41569089  0.41992540 -0.00278664] \t -0.9999002911 \n",
      "87 \t [ 0.41441698  0.41865149 -0.00151273] \t -0.9999318178 \n",
      "88 \t [ 0.41433570  0.41984265 -0.00143145] \t -0.9998956274 \n",
      "88 \t [ 0.41560814  0.41857021 -0.00270389] \t -0.9999305264 \n",
      "89 \t [ 0.41569812  0.41848023 -0.00279387] \t -0.9999307826 \n",
      "89 \t [ 0.41442713  0.41975122 -0.00152288] \t -0.9999000777 \n",
      "90 \t [ 0.41577713  0.41840122 -0.00287288] \t -0.9999307714 \n",
      "90 \t [ 0.41450757  0.41967078 -0.00160333] \t -0.9999037448 \n",
      "91 \t [ 0.41457839  0.41833182 -0.00294228] \t -0.9999061836 \n",
      "91 \t [ 0.41584653  0.41959996 -0.00167414] \t -0.9999408586 \n",
      "92 \t [ 0.41593569  0.41968913 -0.00158498] \t -0.9999425809 \n",
      "92 \t [ 0.41466895  0.41842239 -0.00285172] \t -0.9999093006 \n",
      "93 \t [ 0.41475581  0.41977460 -0.00276486] \t -0.9998786527 \n",
      "93 \t [ 0.41602117  0.41850924 -0.00149950] \t -0.9999680218 \n",
      "94 \t [ 0.41625165  0.41827876 -0.00253301] \t -0.9999500199 \n",
      "94 \t [ 0.41498766  0.41954275 -0.00126902] \t -0.9999274300 \n",
      "95 \t [ 0.41630935  0.41948370 -0.00132807] \t -0.9999591372 \n",
      "95 \t [ 0.41504671  0.41822106 -0.00259071] \t -0.9999299166 \n",
      "96 \t [ 0.41512281  0.41955847 -0.00125330] \t -0.9999309508 \n",
      "96 \t [ 0.41638412  0.41829717 -0.00251461] \t -0.9999519494 \n",
      "97 \t [ 0.41517763  0.41824367 -0.00256811] \t -0.9999326830 \n",
      "97 \t [ 0.41643761  0.41950366 -0.00130812] \t -0.9999615118 \n",
      "98 \t [ 0.41525256  0.41957728 -0.00249318] \t -0.9999068083 \n",
      "98 \t [ 0.41651124  0.41831860 -0.00123450] \t -0.9999811715 \n",
      "99 \t [ 0.41670200  0.41938523 -0.00104373] \t -0.9999718192 \n",
      "99 \t [ 0.41544461  0.41812783 -0.00230112] \t -0.9999470363 \n",
      "100 \t [ 0.41676509  0.41819220 -0.00223676] \t -0.9999646200 \n",
      "100 \t [ 0.41550898  0.41944832 -0.00098064] \t -0.9999471934 \n",
      "101 \t [ 0.41555437  0.41940292 -0.00228089] \t -0.9999245880 \n",
      "101 \t [ 0.41680923  0.41814806 -0.00102604] \t -0.9999884073 \n",
      "102 \t [ 0.41697239  0.41923852 -0.00211649] \t -0.9999583672 \n",
      "102 \t [ 0.41571878  0.41798491 -0.00086288] \t -0.9999799803 \n",
      "103 \t [ 0.41566399  0.41793012 -0.00206046] \t -0.9999594827 \n",
      "103 \t [ 0.41691636  0.41918249 -0.00080809] \t -0.9999806247 \n",
      "104 \t [ 0.41571874  0.41798487 -0.00075455] \t -0.9999810077 \n",
      "104 \t [ 0.41696990  0.41923602 -0.00200570] \t -0.9999610222 \n",
      "105 \t [ 0.41691816  0.41793434 -0.00195396] \t -0.9999745848 \n",
      "105 \t [ 0.41566821  0.41918429 -0.00070402] \t -0.9999594967 \n",
      "106 \t [ 0.41570738  0.41789638 -0.00199193] \t -0.9999621586 \n",
      "106 \t [ 0.41695612  0.41914512 -0.00074319] \t -0.9999822496 \n",
      "107 \t [ 0.41575927  0.41794827 -0.00194004] \t -0.9999633612 \n",
      "107 \t [ 0.41700683  0.41919583 -0.00069248] \t -0.9999826798 \n",
      "108 \t [ 0.41580913  0.41799813 -0.00064378] \t -0.9999829667 \n",
      "108 \t [ 0.41705553  0.41924452 -0.00189017] \t -0.9999646916 \n",
      "109 \t [ 0.41700838  0.41919738 -0.00059779] \t -0.9999833874 \n",
      "109 \t [ 0.41576315  0.41795214 -0.00184303] \t -0.9999655108 \n",
      "110 \t [ 0.41580923  0.41799823 -0.00179694] \t -0.9999665002 \n",
      "110 \t [ 0.41705331  0.41924231 -0.00055286] \t -0.9999836930 \n",
      "111 \t [ 0.41709646  0.41804252 -0.00175265] \t -0.9999793698 \n",
      "111 \t [ 0.41585352  0.41928546 -0.00050971] \t -0.9999626757 \n",
      "112 \t [ 0.41589649  0.41800067 -0.00179450] \t -0.9999676667 \n",
      "112 \t [ 0.41713831  0.41924249 -0.00055268] \t -0.9999848006 \n",
      "113 \t [ 0.41594053  0.41804471 -0.00050976] \t -0.9999849822 \n",
      "113 \t [ 0.41718124  0.41928541 -0.00175046] \t -0.9999687658 \n",
      "114 \t [ 0.41713957  0.41924375 -0.00046920] \t -0.9999852972 \n",
      "114 \t [ 0.41589997  0.41800415 -0.00170880] \t -0.9999694243 \n",
      "115 \t [ 0.41594072  0.41804489 -0.00042954] \t -0.9999854254 \n",
      "115 \t [ 0.41717923  0.41928340 -0.00166805] \t -0.9999704052 \n",
      "116 \t [ 0.41590326  0.41924486 -0.00039208] \t -0.9999651570 \n",
      "116 \t [ 0.41714068  0.41800743 -0.00162951] \t -0.9999822363 \n",
      "117 \t [ 0.41594696  0.41920116 -0.00167214] \t -0.9999514967 \n",
      "117 \t [ 0.41718331  0.41796481 -0.00043578] \t -0.9999970370 \n",
      "118 \t [ 0.41729776  0.41785036 -0.00032134] \t -0.9999984701 \n",
      "118 \t [ 0.41606247  0.41908565 -0.00155663] \t -0.9999580815 \n",
      "119 \t [ 0.41739910  0.41898326 -0.00022000] \t -0.9999921111 \n",
      "119 \t [ 0.41616486  0.41774902 -0.00145424] \t -0.9999799838 \n",
      "120 \t [ 0.41619594  0.41778010 -0.00142316] \t -0.9999805094 \n",
      "120 \t [ 0.41742913  0.41901329 -0.00018996] \t -0.9999921827 \n",
      "121 \t [ 0.41745800  0.41780999 -0.00016110] \t -0.9999994727 \n",
      "121 \t [ 0.41622583  0.41904216 -0.00139327] \t -0.9999645761 \n",
      "122 \t [ 0.41631408  0.41895390 -0.00007387] \t -0.9999787879 \n",
      "122 \t [ 0.41754523  0.41772276 -0.00130501] \t -0.9999899805 \n",
      "123 \t [ 0.41757283  0.41892529 -0.00133262] \t -0.9999841340 \n",
      "123 \t [ 0.41634270  0.41769516 -0.00010249] \t -0.9999943631 \n",
      "124 \t [ 0.41631754  0.41767000 -0.00007733] \t -0.9999943893 \n",
      "124 \t [ 0.41754666  0.41889912 -0.00130645] \t -0.9999845346 \n",
      "125 \t [ 0.41629334  0.41887392 -0.00005313] \t -0.9999797387 \n",
      "125 \t [ 0.41752146  0.41764580 -0.00128125] \t -0.9999903852 \n",
      "126 \t [ 0.41632049  0.41761963 -0.00130741] \t -0.9999848619 \n",
      "126 \t [ 0.41754763  0.41884677 -0.00008028] \t -0.9999948463 \n",
      "127 \t [ 0.41757211  0.41764510 -0.00128195] \t -0.9999904068 \n",
      "127 \t [ 0.41634595  0.41887125 -0.00005580] \t -0.9999805986 \n",
      "128 \t [ 0.41759613  0.41762107 -0.00008079] \t -0.9999999602 \n",
      "128 \t [ 0.41637095  0.41884626 -0.00130597] \t -0.9999714310 \n",
      "129 \t [ 0.41644264  0.41755035 -0.00001006] \t -0.9999962587 \n",
      "129 \t [ 0.41766686  0.41877457 -0.00123428] \t -0.9999874258 \n",
      "130 \t [ 0.41764436  0.41752880 -0.00121178] \t -0.9999914013 \n",
      "130 \t [0.41642109 0.41875207 0.00001149] \t -0.9999834807 \n",
      "131 \t [ 0.41766361  0.41750954 -0.00123104] \t -0.9999910965 \n",
      "131 \t [ 0.41644129  0.41873187 -0.00000872] \t -0.9999840501 \n",
      "132 \t [ 0.41645929  0.41749248 -0.00124810] \t -0.9999876395 \n",
      "132 \t [ 0.41768068  0.41871386 -0.00002672] \t -0.9999967598 \n",
      "133 \t [ 0.41648243  0.41873607 -0.00000451] \t -0.9999845601 \n",
      "133 \t [ 0.41770288  0.41751562 -0.00122497] \t -0.9999911505 \n",
      "134 \t [ 0.41649925  0.41871924 -0.00124087] \t -0.9999760437 \n",
      "134 \t [ 0.41771878  0.41749971 -0.00002134] \t -0.9999998518 \n",
      "135 \t [ 0.41777738  0.41865973 -0.00118136] \t -0.9999895293 \n",
      "135 \t [0.41655876 0.41744112 0.00003726] \t -0.9999976197 \n",
      "136 \t [ 0.41653917  0.41742153 -0.00116086] \t -0.9999897512 \n",
      "136 \t [0.41775688 0.41863923 0.00005685] \t -0.9999976200 \n",
      "137 \t [ 0.41655910  0.41865826 -0.00114093] \t -0.9999790187 \n",
      "137 \t [0.41777590 0.41744145 0.00007587] \t -0.9999996265 \n",
      "138 \t [0.41661050 0.41739095 0.00012638] \t -0.9999980499 \n",
      "138 \t [ 0.41782641  0.41860686 -0.00108953] \t -0.9999912547 \n",
      "139 \t [ 0.41780918  0.41737461 -0.00107230] \t -0.9999927265 \n",
      "139 \t [0.41659416 0.41858963 0.00014272] \t -0.9999877769 \n",
      "140 \t [ 0.41782096  0.41736283 -0.00108408] \t -0.9999925144 \n",
      "140 \t [0.41660681 0.41857698 0.00013007] \t -0.9999881023 \n",
      "141 \t [0.41661812 0.41856567 0.00011876] \t -0.9999883864 \n",
      "141 \t [ 0.41783139  0.41735239 -0.00109452] \t -0.9999923222 \n",
      "142 \t [0.41784065 0.41734314 0.00010863] \t -0.9999991786 \n",
      "142 \t [ 0.41662824  0.41855554 -0.00110377] \t -0.9999816047 \n",
      "143 \t [0.41788345 0.41851189 0.00015143] \t -0.9999986691 \n",
      "143 \t [ 0.41667190  0.41730034 -0.00106012] \t -0.9999922281 \n",
      "144 \t [ 0.41789885  0.41852729 -0.00104387] \t -0.9999924705 \n",
      "144 \t [0.41668815 0.41731659 0.00016683] \t -0.9999986330 \n",
      "145 \t [0.41667345 0.41730189 0.00018153] \t -0.9999986031 \n",
      "145 \t [ 0.41788330  0.41851174 -0.00102832] \t -0.9999926580 \n",
      "146 \t [ 0.41786830  0.41728773 -0.00101332] \t -0.9999929916 \n",
      "146 \t [0.41665929 0.41849674 0.00019569] \t -0.9999895116 \n",
      "147 \t [ 0.41666823  0.41848780 -0.00102143] \t -0.9999838540 \n",
      "147 \t [0.41787641 0.41727963 0.00018675] \t -0.9999987131 \n",
      "148 \t [0.41791235 0.41724368 0.00022269] \t -0.9999983510 \n",
      "148 \t [ 0.41670500  0.41845103 -0.00098466] \t -0.9999850796 \n",
      "149 \t [ 0.41673785  0.41721166 -0.00095181] \t -0.9999940205 \n",
      "149 \t [0.41794438 0.41841819 0.00025472] \t -0.9999989416 \n",
      "150 \t [0.41795599 0.41722408 0.00026633] \t -0.9999979578 \n",
      "150 \t [ 0.41675027  0.41842979 -0.00093939] \t -0.9999862806 \n",
      "151 \t [0.41798406 0.41719600 0.00029440] \t -0.9999976058 \n",
      "151 \t [ 0.41677916  0.41840091 -0.00091050] \t -0.9999871715 \n",
      "152 \t [0.41680498 0.41837508 0.00031943] \t -0.9999919094 \n",
      "152 \t [ 0.41800909  0.41717098 -0.00088468] \t -0.9999933051 \n",
      "153 \t [0.41680878 0.41837129 0.00031563] \t -0.9999919958 \n",
      "153 \t [ 0.41801208  0.41716798 -0.00088768] \t -0.9999932444 \n",
      "154 \t [0.41801472 0.41836786 0.00031220] \t -0.9999990545 \n",
      "154 \t [ 0.41681221  0.41716534 -0.00089032] \t -0.9999949877 \n",
      "155 \t [0.41802421 0.41837734 0.00032168] \t -0.9999990197 \n",
      "155 \t [ 0.41682248  0.41717561 -0.00088004] \t -0.9999950943 \n",
      "156 \t [0.41803334 0.41718553 0.00033082] \t -0.9999971762 \n",
      "156 \t [ 0.41683240  0.41838647 -0.00087013] \t -0.9999882452 \n",
      "157 \t [0.41685443 0.41716427 0.00035208] \t -0.9999989820 \n",
      "157 \t [ 0.41805460  0.41836444 -0.00084810] \t -0.9999955303 \n",
      "158 \t [ 0.41684646  0.41715629 -0.00083935] \t -0.9999955910 \n",
      "158 \t [0.41804586 0.41835570 0.00036005] \t -0.9999989542 \n",
      "159 \t [ 0.41805361  0.41836345 -0.00083084] \t -0.9999956982 \n",
      "159 \t [0.41685497 0.41716481 0.00036780] \t -0.9999989158 \n",
      "160 \t [ 0.41684758  0.41715741 -0.00082268] \t -0.9999957529 \n",
      "160 \t [0.41804546 0.41835530 0.00037520] \t -0.9999988899 \n",
      "161 \t [0.41805266 0.41716536 0.00038239] \t -0.9999967539 \n",
      "161 \t [ 0.41685553  0.41836249 -0.00081473] \t -0.9999892290 \n",
      "162 \t [0.41687405 0.41834397 0.00040016] \t -0.9999924968 \n",
      "162 \t [ 0.41807043  0.41714759 -0.00079621] \t -0.9999937187 \n",
      "163 \t [ 0.41807300  0.41834066 -0.00079879] \t -0.9999960754 \n",
      "163 \t [0.41687736 0.41714502 0.00039685] \t -0.9999988602 \n",
      "164 \t [ 0.41687103  0.41713869 -0.00079172] \t -0.9999961189 \n",
      "164 \t [0.41806593 0.41833359 0.00040318] \t -0.9999988369 \n",
      "165 \t [ 0.41687793  0.41833975 -0.00078482] \t -0.9999899155 \n",
      "165 \t [0.41807209 0.41714559 0.00040935] \t -0.9999964131 \n",
      "166 \t [0.41808733 0.41713035 0.00042459] \t -0.9999961649 \n",
      "166 \t [ 0.41689390  0.41832379 -0.00076885] \t -0.9999903397 \n",
      "167 \t [ 0.41690823  0.41830945 -0.00075451] \t -0.9999907148 \n",
      "167 \t [0.41810094 0.41711674 0.00043820] \t -0.9999959355 \n",
      "168 \t [0.41692110 0.41829658 0.00045035] \t -0.9999930648 \n",
      "168 \t [ 0.41811309  0.41710459 -0.00074164] \t -0.9999937046 \n",
      "169 \t [ 0.41811427  0.41710342 -0.00074282] \t -0.9999936800 \n",
      "169 \t [0.41692299 0.41829469 0.00044846] \t -0.9999931059 \n",
      "170 \t [0.41692472 0.41829297 0.00044673] \t -0.9999931442 \n",
      "170 \t [ 0.41811529  0.41710240 -0.00074384] \t -0.9999936598 \n",
      "171 \t [0.41692630 0.41829138 0.00044515] \t -0.9999931792 \n",
      "171 \t [ 0.41811617  0.41710152 -0.00074472] \t -0.9999936403 \n",
      "172 \t [0.41692775 0.41828993 0.00044370] \t -0.9999932102 \n",
      "172 \t [ 0.41811692  0.41710077 -0.00074547] \t -0.9999936238 \n",
      "173 \t [0.41811755 0.41710013 0.00044236] \t -0.9999957126 \n",
      "173 \t [ 0.41692909  0.41828860 -0.00074610] \t -0.9999911377 \n",
      "174 \t [ 0.41694033  0.41827736 -0.00073486] \t -0.9999914193 \n",
      "174 \t [0.41812810 0.41708958 0.00045291] \t -0.9999955254 \n",
      "175 \t [ 0.41813753  0.41708016 -0.00072475] \t -0.9999935429 \n",
      "175 \t [0.41695044 0.41826725 0.00046234] \t -0.9999934818 \n",
      "176 \t [ 0.41813733  0.41826676 -0.00072455] \t -0.9999968993 \n",
      "176 \t [0.41695093 0.41708035 0.00046185] \t -0.9999987007 \n",
      "177 \t [0.41813272 0.41707642 0.00046579] \t -0.9999953432 \n",
      "177 \t [ 0.41694699  0.41826214 -0.00071994] \t -0.9999917220 \n",
      "178 \t [0.41695591 0.41825322 0.00047404] \t -0.9999935722 \n",
      "178 \t [ 0.41814097  0.41706816 -0.00071101] \t -0.9999935580 \n",
      "179 \t [ 0.41814060  0.41825292 -0.00071064] \t -0.9999970281 \n",
      "179 \t [0.41695622 0.41706853 0.00047374] \t -0.9999986485 \n",
      "180 \t [ 0.41695271  0.41824875 -0.00070648] \t -0.9999919850 \n",
      "180 \t [0.41813643 0.41706503 0.00047724] \t -0.9999951820 \n",
      "181 \t [ 0.41814366  0.41705780 -0.00069859] \t -0.9999935737 \n",
      "181 \t [0.41696060 0.41824086 0.00048447] \t -0.9999936481 \n",
      "182 \t [0.41814315 0.41705831 0.00048431] \t -0.9999950540 \n",
      "182 \t [ 0.41696076  0.41824070 -0.00069808] \t -0.9999921794 \n",
      "183 \t [0.41814961 0.41823359 0.00049077] \t -0.9999985773 \n",
      "183 \t [ 0.41696787  0.41705185 -0.00069097] \t -0.9999971889 \n",
      "184 \t [ 0.41815256  0.41705545 -0.00068737] \t -0.9999935902 \n",
      "184 \t [0.41697146 0.41823654 0.00049372] \t -0.9999937131 \n",
      "185 \t [0.41815194 0.41823651 0.00049368] \t -0.9999985604 \n",
      "185 \t [ 0.41697150  0.41705606 -0.00068676] \t -0.9999972228 \n",
      "186 \t [ 0.41815477  0.41705953 -0.00068329] \t -0.9999936338 \n",
      "186 \t [0.41697497 0.41823933 0.00049651] \t -0.9999937022 \n",
      "187 \t [ 0.41815429  0.41823917 -0.00068281] \t -0.9999972701 \n",
      "187 \t [0.41697512 0.41706001 0.00049635] \t -0.9999985365 \n",
      "188 \t [ 0.41815100  0.41705735 -0.00067952] \t -0.9999936761 \n",
      "188 \t [0.41697247 0.41823588 0.00049901] \t -0.9999936958 \n",
      "189 \t [ 0.41697274  0.41705772 -0.00067916] \t -0.9999972837 \n",
      "189 \t [0.41815064 0.41823561 0.00049874] \t -0.9999985307 \n",
      "190 \t [ 0.41697597  0.41706095 -0.00067592] \t -0.9999973092 \n",
      "190 \t [0.41815324 0.41823822 0.00050134] \t -0.9999985156 \n",
      "191 \t [ 0.41697911  0.41706409 -0.00067279] \t -0.9999973338 \n",
      "191 \t [0.41815575 0.41824073 0.00050386] \t -0.9999985008 \n",
      "192 \t [ 0.41815817  0.41824315 -0.00066975] \t -0.9999973726 \n",
      "192 \t [0.41698215 0.41706713 0.00050627] \t -0.9999984785 \n",
      "193 \t [ 0.41697987  0.41706485 -0.00066686] \t -0.9999973803 \n",
      "193 \t [0.41815528 0.41824026 0.00050855] \t -0.9999984732 \n",
      "194 \t [ 0.41815753  0.41824250 -0.00066400] \t -0.9999974169 \n",
      "194 \t [0.41698273 0.41706771 0.00051079] \t -0.9999984515 \n",
      "195 \t [ 0.41815481  0.41823979 -0.00066129] \t -0.9999974373 \n",
      "195 \t [0.41698062 0.41706560 0.00051290] \t -0.9999984390 \n",
      "196 \t [0.41815217 0.41706357 0.00051493] \t -0.9999948505 \n",
      "196 \t [ 0.41697859  0.41823715 -0.00065865] \t -0.9999926575 \n",
      "197 \t [0.41698400 0.41823175 0.00051973] \t -0.9999936914 \n",
      "197 \t [ 0.41815697  0.41705877 -0.00065325] \t -0.9999938478 \n",
      "198 \t [0.41698466 0.41823108 0.00051907] \t -0.9999937061 \n",
      "198 \t [ 0.41815704  0.41705871 -0.00065331] \t -0.9999938477 \n",
      "199 \t [0.41815707 0.41823046 0.00051844] \t -0.9999984197 \n",
      "199 \t [ 0.41698529  0.41705868 -0.00065334] \t -0.9999974902 \n",
      "200 \t [ 0.41698774  0.41823232 -0.00065089] \t -0.9999928221 \n",
      "200 \t [0.41815893 0.41706113 0.00052030] \t -0.9999947583 \n",
      "SPSA结果： -0.9999999602239835\n"
     ]
    }
   ],
   "source": [
    "# 测试SPSA算法\n",
    "print(\"=\"*50)\n",
    "print(\"运行SPSA\")\n",
    "param_init = {'t1':np.random.randn(), 't2':np.random.randn(), 't3':np.random.randn()}\n",
    "spsa_optimizer = OptimizerSPSA(target_func=void_target,param_init=param_init,random_state=0)\n",
    "\n",
    "print(\"轮次\",\"\\t\",\"参数值\",\"\\t\",\" \"*31,\"目标值\")\n",
    "for _ in range(200):\n",
    "    # 待片上计算的两组参数\n",
    "    p1,p2 = spsa_optimizer.param_suggest()\n",
    "    # 以下两行模拟芯片计算过程，之后需要替换成接口\n",
    "    f1 = estimate_eigval(p1.tolist())\n",
    "    f2 = estimate_eigval(p2.tolist())\n",
    "    # 测试结果传回，更新param_dict\n",
    "    spsa_optimizer.param_register([p1,p2],[f1,f2])\n",
    "    # spsa_optimizer.param_register(np.array([p1,p2]),np.array([f1,f2]))\n",
    "    \n",
    "\n",
    "    if f1<0:\n",
    "        print(spsa_optimizer.iter,\"\\t\",p1,\"\\t\",f\"{f1:8.10f} \")\n",
    "    else:\n",
    "        print(spsa_optimizer.iter,\"\\t\",p1,\"\\t \",f\"{f1:8.10f} \")\n",
    "    if f2<0:\n",
    "        print(spsa_optimizer.iter,\"\\t\",p2,\"\\t\",f\"{f2:8.10f} \")\n",
    "    else:\n",
    "        print(spsa_optimizer.iter,\"\\t\",p2,\"\\t \",f\"{f2:8.10f} \")\n",
    "    # print(spsa_optimizer.hyperparam['c']/(1+spsa_optimizer.iter)**spsa_optimizer.hyperparam['gamma'])\n",
    "\n",
    "    if (f1<-0.92) and (f2<-0.92):\n",
    "        # print(\"!!!进入步长减小阶段!!!\")\n",
    "        spsa_optimizer.hyperparam['c'] = 0.001\n",
    "    elif (f1<-0.999) and (f2<-0.999):\n",
    "        spsa_optimizer.hyperparam['c'] = 1e-4\n",
    "\n",
    "print(\"SPSA结果：\",estimate_eigval(list(spsa_optimizer.best_param_dict.values())))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "==================================================\n",
      "运行Fourier级数法\n",
      "轮次 \t 参数值 \t                                 目标值\n",
      "1 \t [0.15650654 0.23218104 0.00000000] \t -0.9261000639 \n",
      "2 \t [0.24215053 0.31843215 0.00000000] \t -0.9627085499 \n",
      "3 \t [0.36816295 0.44202150 0.00000000] \t -0.9825996643 \n",
      "4 \t [0.48253207 0.53621082 0.00000000] \t -0.9939607867 \n",
      "5 \t [0.58076884 0.61726507 0.00000000] \t -0.9979074916 \n",
      "6 \t [0.66189373 0.68684693 0.00000000] \t -0.9992018447 \n",
      "7 \t [0.72702523 0.74424278 0.00000000] \t -0.9996709109 \n",
      "8 \t [0.77912714 0.79110559 0.00000000] \t -0.9998564422 \n",
      "9 \t [0.82125658 0.82965201 0.00000000] \t -0.9999347453 \n",
      "10 \t [0.85587451 0.86179790 0.00000000] \t -0.9999693953 \n",
      "11 \t [0.88480355 0.88900769 0.00000000] \t -0.9999852905 \n",
      "12 \t [0.90936326 0.91236305 0.00000000] \t -0.9999927905 \n",
      "13 \t [0.93051067 0.93266128 0.00000000] \t -0.9999964111 \n",
      "14 \t [0.94894796 0.95049632 0.00000000] \t -0.9999981874 \n",
      "15 \t [0.96519833 0.96631738 0.00000000] \t -0.9999990743 \n",
      "16 \t [0.97965793 0.98046950 0.00000000] \t -0.9999995225 \n",
      "17 \t [0.99263158 0.99322196 0.00000000] \t -0.9999997514 \n",
      "18 \t [1.00435732 1.00478802 0.00000000] \t -0.9999998697 \n",
      "19 \t [1.01502363 1.01533867 0.00000000] \t -0.9999999312 \n",
      "20 \t [1.02478177 1.02501276 0.00000000] \t -0.9999999635 \n",
      "21 \t [1.03375457 1.03392431 0.00000000] \t -0.9999999805 \n",
      "22 \t [1.04204280 1.04216780 0.00000000] \t -0.9999999895 \n",
      "23 \t [1.04973008 1.04982226 0.00000000] \t -0.9999999944 \n",
      "24 \t [1.05688629 1.05695439 0.00000000] \t -0.9999999969 \n",
      "25 \t [1.06357045 1.06362086 0.00000000] \t -0.9999999983 \n",
      "26 \t [1.06983270 1.06987008 0.00000000] \t -0.9999999991 \n",
      "27 \t [1.07571608 1.07574377 0.00000000] \t -0.9999999995 \n",
      "28 \t [1.08125759 1.08127816 0.00000000] \t -0.9999999997 \n",
      "29 \t [1.08648936 1.08650464 0.00000000] \t -0.9999999998 \n",
      "30 \t [1.09143943 1.09145079 0.00000000] \t -0.9999999999 \n",
      "31 \t [1.09613236 1.09614085 0.00000000] \t -1.0000000000 \n",
      "32 \t [1.10058988 1.10059617 0.00000000] \t -1.0000000000 \n",
      "33 \t [1.10483105 1.10483574 0.00000000] \t -1.0000000000 \n",
      "34 \t [1.10887296 1.10887649 0.00000000] \t -1.0000000000 \n",
      "35 \t [1.11273082 1.11273347 0.00000000] \t -1.0000000000 \n",
      "36 \t [1.11641822 1.11642019 0.00000000] \t -1.0000000000 \n",
      "37 \t [1.11994739 1.11994888 0.00000000] \t -1.0000000000 \n",
      "38 \t [1.12332937 1.12333051 0.00000000] \t -1.0000000000 \n",
      "39 \t [1.12657412 1.12657502 0.00000000] \t -1.0000000000 \n",
      "40 \t [1.12969076 1.12969143 0.00000000] \t -1.0000000000 \n",
      "41 \t [1.13268745 1.13268795 0.00000000] \t -1.0000000000 \n",
      "42 \t [1.13557170 1.13557206 0.00000000] \t -1.0000000000 \n",
      "43 \t [1.13557170 1.13557206 0.00000000] \t -1.0000000000 \n",
      "44 \t [1.14102965 1.14102986 0.00000000] \t -1.0000000000 \n",
      "45 \t [1.14102965 1.14102986 0.00000000] \t -1.0000000000 \n",
      "46 \t [1.14611299 1.14611307 0.00000000] \t -1.0000000000 \n",
      "47 \t [1.14852718 1.14852724 0.00000000] \t -1.0000000000 \n",
      "48 \t [1.14852718 1.14852724 0.00000000] \t -1.0000000000 \n",
      "49 \t [1.14852718 1.14852724 0.00000000] \t -1.0000000000 \n",
      "50 \t [1.14852718 1.14852724 0.00000000] \t -1.0000000000 \n",
      "Fourier结果： -0.9999999999999458\n"
     ]
    }
   ],
   "source": [
    "# 测试Fourier级数方法\n",
    "print(\"=\"*50)\n",
    "print(\"运行Fourier级数法\")\n",
    "param_init = {'t1':np.random.randn(), 't2':np.random.randn(), 't3':np.random.randn()}\n",
    "# param_init = dict(zip(param_init.keys(),np.random.randn(3)))\n",
    "fourier_optimizer = OptimizerFourier(target_func=void_target,param_init=param_init,random_state=0,order=3,lr=0.1)\n",
    "print(\"轮次\",\"\\t\",\"参数值\",\"\\t\",\" \"*31,\"目标值\")\n",
    "for _ in range(50):\n",
    "    # 待片上计算的两组参数\n",
    "    param_array = fourier_optimizer.param_suggest()\n",
    "    # 模拟芯片计算过程，之后需要替换成接口\n",
    "    target = np.zeros(len(param_array))\n",
    "    for i in range(len(param_array)):\n",
    "        target[i] = estimate_eigval(param_array[i])\n",
    "\n",
    "    # 测试结果传回，更新param_dict\n",
    "    fourier_optimizer.param_register(param_array,target)\n",
    "    p1 = np.array(list(fourier_optimizer.best_param_dict.values()))\n",
    "    f1 = fourier_optimizer.best_target\n",
    "    if f1<0:\n",
    "        print(fourier_optimizer.iter,\"\\t\",p1,\"\\t\",f\"{f1:8.10f} \")\n",
    "    else:\n",
    "        print(fourier_optimizer.iter,\"\\t\",p1,\"\\t \",f\"{f1:8.10f} \")\n",
    "\n",
    "print(\"Fourier结果：\",estimate_eigval(list(fourier_optimizer.best_param_dict.values())))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "deepquantum",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
